package com.company.zhishidian.thread.生产者消费者;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class MyArrayBlockingQueue<T> {
    private final Object[] arr = new Object[5];
    private int size = 0;
    private ReentrantLock lock = new ReentrantLock();
    // 条件
    private Condition notFull = lock.newCondition();
    private Condition notEmpty = lock.newCondition();

    public void put(T t){
        lock.lock();
        try{
            // 容器满了
            while (size==arr.length){
                System.out.println("生产者等待");
                notFull.await();  // 等待
            }
            arr[size++] = t;
            notFull.signalAll();  // 唤醒其他线程，告诉别人有了
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public T get() throws InterruptedException {
        lock.lock();
        try{
            // 容器满了
            while (size==0){
                System.out.println("消费者等待");
                notEmpty.await(); // 消费者线程等待
            }
            Object temp = arr[--size];
            notFull.signalAll();  // 唤醒其他线程，告诉别人有了
            return (T)temp;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        MyArrayBlockingQueue<String> q = new MyArrayBlockingQueue<>();
        // 生产者
        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(100);
                    q.put("aaa");
                    System.out.println("生产者放入了一个东西");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }).start();

        new Thread(()->{
            while (true){
                try {
                    Thread.sleep(1000);
                    q.get();
                    System.out.println("消费者取了一个东西");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }).start();
    }
}
